from typing import Any, Dict, Set
from dataclasses import dataclass

# ------------------------------
# 项目基础信息定义（可扩展字段）
# ------------------------------
PROJECT_BASE_INFO ={
    '施工单位':'浙江交工宏途交通建设有限公司',
    '监理单位':'浙江浙中建设工程管理有限公司',
    '单位工程':'路基工程',
    '分部工程':'涵洞、通道',
    '分项工程':'主体结构',
    '施工日期':'2024/05/31',
    '施工部位':'K59+639圆管涵',
    '签字时间':'2024/05/31',
    '开工日期':'2024/05/01',
    '设计坐标(X,Y)':(3243273.926,509154.842),
    '长':44.5,
    '宽':4,
    '基础宽度':2759,
    '基础厚度':300,
    '基础顶高程':66035,
    '设计高程':66,
    '断面尺寸长度':1250,
    '断面尺寸宽度':275.9,
    '断面尺寸高(厚)度':30,
    '基础混凝土强度（砂浆）等级':'C25',
    '基础设计混凝土（砂浆）用量':'15',
    '基础实际混凝土（砂浆）用量':'16',
    '护壁混凝土强度（砂浆）等级':'C25',
    '护壁设计混凝土（砂浆）用量':'15',
    '护壁实际混凝土（砂浆）用量':'16',
    
}
# ------------------------------
# 必要字段定义（用于校验）
# ------------------------------
REQUIRED_FIELDS: Set[str] = {
    "施工单位", "监理单位", "单位工程", 
    "分部工程", "分项工程", "设计坐标(X,Y)"
}

# ------------------------------
# 字段类型约束（用于校验）
# ------------------------------
FIELD_TYPES: Dict[str, type] = {
    "施工单位": str,
    "监理单位": str,
    "单位工程": str,
    "分部工程": str,
    "分项工程": str,
    "设计坐标(X,Y)": tuple,
    "施工日期": str,
    "开工日期": str
}

# ------------------------------
# 信息校验器（核心功能）
# ------------------------------
class ProjectInfoValidator:
    """项目基础信息校验器"""
    
    @staticmethod
    def validate(info: Dict[str, Any]) -> None:
        """
        校验项目基础信息完整性和字段类型
        :param info: 待校验的项目信息字典
        :raises ValueError: 校验失败时抛出异常
        """
        # 校验1：必要字段是否存在
        missing_fields = REQUIRED_FIELDS - set(info.keys())
        if missing_fields:
            raise ValueError(f"项目信息缺失必要字段: {missing_fields}")

        # 校验2：字段类型是否符合要求
        for field, value in info.items():
            expected_types = FIELD_TYPES.get(field, (object,))
            if not isinstance(expected_types, tuple):
                expected_types = (expected_types,)
            
            if not any(isinstance(value, t) for t in expected_types):
                raise ValueError(
                    f"字段类型错误: 字段'{field}'预期类型为{expected_types}，实际类型为{type(value)}"
                )

        # 校验3：日期格式（示例扩展校验）
        for date_field in ["施工日期", "开工日期"]:
            if date_field in info:
                ProjectInfoValidator._validate_date_format(info[date_field])

    @staticmethod
    def _validate_date_format(date_str: str) -> None:
        """校验日期格式（YYYY/MM/DD）"""
        if not isinstance(date_str, str):
            return  # 类型校验已在前面完成
        
        try:
            parts = date_str.split("/")
            if len(parts) != 3 or len(parts[0]) != 4 or len(parts[1]) != 2 or len(parts[2]) != 2:
                raise ValueError
        except:
            raise ValueError(f"日期字段格式错误（需为YYYY/MM/DD）: {date_str}")

# ------------------------------
# 校验入口（确保信息有效性）
# ------------------------------
if __name__ == "__main__":
    # 示例：校验内置项目信息
    try:
        ProjectInfoValidator.validate(PROJECT_BASE_INFO)
        print("项目基础信息校验通过 ✅")
    except ValueError as e:
        print(f"项目基础信息校验失败 ❌: {e}")
